#include "console.h"

#include "devices.h"
#include <um.h>

static int tty;
//static struct termios default_settings;

//static pthread_t _daemon;  /* just avoid redeclaring */


/**
 * The daemon who collects input characters and deliver signals to the main process.
 * TODO: what should be done if we don't have pthread?
 */
static void*
cons_daemon (void* dummy) 
{
	while (1) {
		//read (tty, &(device_common->cons_buffer[device_common->cons_end]), 1);
		device_common->cons_end = (device_common->cons_end+1) % CONSOLE_BUFFER_SIZE;
		//kill (device_common->cpid, SIGIO);
	}
	
	return 0;
}

/**
 * open /dev/tty as the console device and adjust the terminal's attributes
 */
void
cons_init()
{
	//struct termios raw_settings;
		
	//tty = open ("/dev/tty", O_RDWR);
	char tty_name[] = "/dev/tty";
	syscall2 (__NR_open, (long)tty_name, O_RDWR);
	
	if (tty == -1) {
		syscall1 (__NR_exit, 1);
	}
	
	/* tcgetattr (tty, &default_settings); */
	/* raw_settings = default_settings; */
	/* raw_settings.c_iflag &= ~(IGNBRK | BRKINT | INLCR | IGNCR | IXON); */
	/* raw_settings.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN); */
	/* raw_settings.c_cflag &= ~(CSIZE | PARENB); */
	/* raw_settings.c_cflag |= CS8; */
	/* tcsetattr (tty, TCSANOW, &raw_settings); */

	/* Initialize the daemon thread */
	//pthread_create (&_daemon, 0, cons_daemon, 0);
}

/**
 * close /dev/tty, reset the terminal's attributes, stop daemon and release shared memory.
 */
void
cons_dtor (void)
{
	//tcsetattr (tty, TCSANOW, &default_settings);
	//close (tty);
	syscall1 (__NR_close, tty);
	//pthread_cancel (_daemon);
}


/**
 * put a character to the console (tty here)
 * @param c the character to be put
 * TODO: we need tty driver
 */
void
cons_putc(int c)
{
	char buf = (char)c;
	//write (tty, &buf, 1);
	//syscall3 (__NR_write, tty, (long)&buf, 1);
	syscall3 (__NR_write, 1, (long)&buf, 1);
}

/**
 * get a character from the console (tty here)
 * @return the charater got
 */
int
cons_getc(void) 
{
	int c;
	if (device_common->cons_end != device_common->cons_front) {
		c = (int)device_common->cons_buffer[device_common->cons_front];
		device_common->cons_front = (device_common->cons_front+1) % CONSOLE_BUFFER_SIZE;
	} else {
		/* !TODO We should arrange other guest's 'process' running here in the future. */
		c = 0;
	}
	return c;
}

/**
 * !TODO
 */
void
serial_intr(void)
{
}

/**
 * !TODO
 */
void
kbd_intr(void) 
{
}
